// 变量初始化
var MarsJSBridge = new MarsJSBridgeImpl();
var callBackMap = new MarsMap();

// 桥接实现
function MarsJSBridgeImpl() {
    // 获取回调
    function makeCallBack(params) {
        for (var key in params) {
            const item = params[key];
            if (typeof item == "function") {
                // 参数的值对应的是方法类型，则建立参数中的 value 为 function 类型的映射关系
                // 生成随机的 callBackId
                var nativeCallBackId = "Mars_" + Math.random().toString(36).substr(2);
                // callBackMap 存放 callBackId 和方法的映射
                callBackMap.put(nativeCallBackId, item);
                // params 修改 key 的映射为 callbackId
                params[key] = nativeCallBackId;
            } else if (typeof item == "object") {
                // 参数对应的值是对象类型，则递归
                params[key] = makeCallBack(item);
            }
        }
        return params;
    }
    
    // 前端调用客户端方法，funcName - 客户端方法， params-参数，callBack-客户端执行结束回调
    this.invoke = function(funcName, params, callBack) {
        if (params == undefined) {
            params = {};
        }
        var paramsObj = makeCallBack(params);
        paramsObj.methodName = funcName + ":";
        if (typeof callBack != "function") {
            callBack = "";
        } else {
            // 建立客户端执行结束回调的映射
            var nativeCallBackId = "Mars_" + Math.random().toString(36).substr(2);
            callBackMap.put(nativeCallBackId, callBack);
            paramsObj.nativeCallBack = nativeCallBackId;
        }
        console.info("H5>>>>>>Native>>>>>调用客户端方法："， paramsObj.methodName);
        console.info("H5>>>>>>Native>>>>>传递客户端参数："， JSON.stringify(paramsObj));
        window.webkit.messageHandlers.native.postMessage(paramsObj);
    };
    
    window.MarsJSBridge = MarsJSBridge;
    window.callBackMap = callBackMap;
    window.nativeDispatchEvent = nativeDispatchEvent;
    
    // 错误信息输出给客户端
    window.onerror = function(msg, url, line, column, error) {
        const message = {
            msg:msg,
            url:url,
            line:line,
            column:column,
            error:JSON.stringify(error)
        }
        window.webkit.messageHandlers.logger.postMessage(error);
    };
}

// 客户端执行的回调方法
function onCallBack (result) {
    try {
        var paramResult = result;
        var callBackId = paramResult.callBackId;
        var callBack = window.callBackMap.get(callBackId);
        if (callBack != null) {
            console.info("Native >>>>> H5");
            callBack(paramResult);
            return;
        } else {
            console.log("callBackMap: " + JSON.stringify(window.callBackMap));
        }
    } catch (error) {
        console.log("onCallBack error: "+ error.message);
    }
}

// 客户端触发通知时间
function nativeDispatchEvent(jsEvent) {
    try {
        var readyEvent = document.createEvent("Events");
        readyEvent.initEvent(jsEvent);
        document.dispatchEvent(readyEvent);
    } catch (error) {
        console.log("onInit error: "+ error.message);
    }
}


// 回调隐射
function MarsMap() {
    this.map = {}
    this.length = 0;
    this.size = function() {
        return this.length;
    };
    this.put = function(a, b) {
        if (!this.map["_" + a]) {
            ++this.length;
        }
        this.map["_" + a] = b;
    };
    this.remove = function (a) {
        if (this.map["_" + a]) {
            --this.length;
            return delete this.map["_" + a];
        } else {
            return false;
        }
    };
    this.containsKey = function (a) {
        return this.map["_" + a] ? true : false;
    };
    this.get = function(a) {
        return this.map["_" + a] ? this.map["_" + a] : null;
    };
    this.toString = function() {
        var b = "";
        for (var a in this.map) {
            b += "\n" + a + "-" + this.map[a];
        }
        return b;
    };
}
